package com.example.demo.service.system.impl;

import com.example.demo.entity.CollectionName;
import com.example.demo.entity.Result;
import com.example.demo.service.system.HomePageTitleService;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @description:
 * @author: cj
 * @create: 17-01-10 17:29:02
 */
@Service
public class HomePageTitleServiceImpl implements HomePageTitleService {
    @Resource
    MongoTemplate mongoTemplate;

    /**
     * 标题操作
     *
     * @param map 操作map （handle 为 find insert 和修改）
     */
    @Override
    public Result handleHomePage(Map<String, Object> map) {
        String handle = map.get( "handle" ).toString();
        map.remove( "handle" );
        if (CollectionName.FIND.equalsIgnoreCase( handle )) {
            List<Map> all = mongoTemplate.findAll( Map.class, CollectionName.SYSTEM_HOME_PAGE );
            if (!CollectionUtils.isEmpty( all )) {
                return Result.ok( all.get( 0 ) );
            }

        } else if (CollectionName.INSERT.equalsIgnoreCase( handle )) {
            mongoTemplate.remove( Query.query( new Criteria() ), CollectionName.SYSTEM_HOME_PAGE );
            Map<String, Object> insert = mongoTemplate.insert( map, CollectionName.SYSTEM_HOME_PAGE );
            insert.put( "_id", insert.get( "_id" ).toString() );
            return Result.ok( insert );
        } else {
            Update update = new Update();
            Set<String> strings = map.keySet();
            Iterator<String> iterator = strings.iterator();
            while (iterator.hasNext()) {
                String next = iterator.next();
                update = update.set( next, map.get( next ) );
            }
            mongoTemplate.updateFirst( Query.query( new Criteria() ), update, CollectionName.SYSTEM_HOME_PAGE );
            return Result.ok( "修改成功" );
        }
        return Result.ok( "暂无数据" );
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        //1.获取通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        //2.切换非阻塞模式
        serverSocketChannel.configureBlocking(false);

        //3.绑定连接
        serverSocketChannel.bind(new InetSocketAddress(9999));

        //4.获取选择器
        Selector selector = Selector.open();


        //5.将通道注册到选择器上,并且指定“监听事件”
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);//第二个参数时选择键，用于通道向选择器注册哪种事件，可以将多个事件使用|进行组合。

        //6.轮询式获取选择器上已经“准备就绪”的事件
        while (selector.select() > 0) {
            //7.获取当前选择器中所有注册的“选择键（）已经就绪的事件”
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();

            while (iterator.hasNext()) {
                //8.获取“准备就绪”的事件
                SelectionKey sk = iterator.next();

                //9.判断具体时什么事件准备就绪
                if (sk.isAcceptable()) {
                    //10.若“接收事件就绪”，获取客户端连接
                    SocketChannel socketChannel = serverSocketChannel.accept();

                    //11.切换非阻塞模式
                    socketChannel.configureBlocking(false);

                    //12.将该通道注册到选择器上
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else if (sk.isReadable()) {
                    //13.获取当前选择器上“读就绪”状态的通道
                    SocketChannel socketChannel = (SocketChannel) sk.channel();

                    //14.读取数据
                    ByteBuffer buf = ByteBuffer.allocate(1024);
                    int len;
                    while ((len = socketChannel.read(buf)) > 0) {
                        buf.flip();
                        System.out.println(new String(buf.array(), 0, len));
                        buf.clear();
                    }
                }
                //15.取消选择键SelectionKey
                iterator.remove();
            }
        }
    }

}

